package com.tjetc.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tjetc.constant.RedisConstant;
import com.tjetc.constant.SchedulingConstant;
import com.tjetc.domain.Hospital;
import com.tjetc.mapper.ClinicMapper;
import com.tjetc.mapper.HospitalMapper;
import com.tjetc.mapper.RankRecordMapper;
import com.tjetc.util.DateUtil;
import com.tjetc.util.Db;
import com.tjetc.vo.Result;
import com.tjetc.vo.SchedulingDateVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import com.tjetc.domain.Scheduling;
import com.tjetc.mapper.SchedulingMapper;
import com.tjetc.service.SchedulingService;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class SchedulingServiceImpl implements SchedulingService {

    @Resource
    private SchedulingMapper schedulingMapper;

    @Autowired
    private HospitalMapper hospitalMapper;

    private ObjectMapper objectMapper = new ObjectMapper();
    @Autowired
    private RankRecordMapper rankRecordMapper;

    @Override
    public int deleteByPrimaryKey(Integer id) {
        return schedulingMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int insert(Scheduling record) {
        return schedulingMapper.insert(record);
    }

    @Override
    public int insertSelective(Scheduling record) {
        return schedulingMapper.insertSelective(record);
    }

    @Override
    public Scheduling selectByPrimaryKey(Integer id) {
        return schedulingMapper.selectByPrimaryKey(id);
    }

    @Override
    public int updateByPrimaryKeySelective(Scheduling record) {
        return schedulingMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public int updateByPrimaryKey(Scheduling record) {
        return schedulingMapper.updateByPrimaryKey(record);
    }

    @Override
    public Result getState(Integer cid) throws JsonProcessingException {
        String res = Db.jedis.get(RedisConstant.SCHEDULING_STATE + cid + "-" + DateUtil.getDate(new Date()));
        if (res != null && !res.isEmpty()) {
            return Result.ok(objectMapper.readValue(res, List.class));
        }
        List<SchedulingDateVo> schedulingDateVos = new ArrayList<>();
        for (int i = 0; i < 8; i++) {
            Date date = new Date(new Date().getTime() + i * 24 * 60 * 60 * 1000);
            SchedulingDateVo schedulingDateVo = new SchedulingDateVo();
            schedulingDateVo.setDate(date);
            schedulingDateVo.setDateStr(DateUtil.getDateWithNotYear(date));
            schedulingDateVo.setWeek(DateUtil.getWeek(date));
            if (i == 7) {
                schedulingDateVo.setState(SchedulingConstant.UPCOMING_ACCOUNT);
                schedulingDateVos.add(schedulingDateVo);
                continue;
            }
            List<Scheduling> schedulings = schedulingMapper.selectByCidAndDate(cid, DateUtil.getDate(date));
            if (schedulings.isEmpty()) {
                schedulingDateVo.setState(SchedulingConstant.NO_NUMBER);
                schedulingDateVos.add(schedulingDateVo);
                continue;
            }
            boolean find = false;
            for (Scheduling scheduling : schedulings) {
                if (scheduling.getLeaveCount() != 0) {
                    schedulingDateVo.setState(SchedulingConstant.HAVE_NUMBER);
                    schedulingDateVos.add(schedulingDateVo);
                    System.out.println(schedulingDateVo.getState());
                    find = true;
                    break;
                }
            }
            if (find) {
                continue;
            }
            Hospital hospital = hospitalMapper.selectByCid(cid);
            if (hospital.getIsAlternate() == 1) {
                schedulingDateVo.setState(SchedulingConstant.ALTERNATE);
                schedulingDateVos.add(schedulingDateVo);
                continue;
            }
            schedulingDateVo.setState(SchedulingConstant.FULL);
            schedulingDateVos.add(schedulingDateVo);
        }
        Db.jedis.set(RedisConstant.SCHEDULING_STATE + cid + "-" + DateUtil.getDate(new Date()), objectMapper.writeValueAsString(schedulingDateVos));
        Db.jedis.expire(RedisConstant.SCHEDULING_STATE + cid + "-" + DateUtil.getDate(new Date()), 60 * 60 * 24);
        return Result.ok(schedulingDateVos);
    }

    @Override
    public Result getSchedulingList(Integer cid, Date date) {
        List<Scheduling> schedulings = schedulingMapper.selectByCidAndDate(cid, DateUtil.getDate(date));
        return Result.ok(schedulings);
    }

    @Override
    public Result delete(Integer id) {
        Scheduling scheduling = schedulingMapper.selectByPrimaryKey(id);
        if (scheduling == null){
            return Result.fail("该排班记录不存在");
        }
        Integer count = rankRecordMapper.selectCountBySid(id);
        if (count > 0){
            return Result.fail("已有用户预约挂号,只能换班不可删除");
        }
        int rows = schedulingMapper.deleteByPrimaryKey(id);
        Db.jedis.del(RedisConstant.SCHEDULING_STATE + scheduling.getCid() + "-" + DateUtil.getDate(new Date()));
        return rows == 1 ? Result.ok() : Result.fail("删除失败");
    }

    @Override
    public Result add(Scheduling scheduling) {
        //看医生是否排班冲突
        Integer doctorConflict = schedulingMapper.selectDoctorConflict(scheduling);
        if (doctorConflict >= 1){
            return Result.fail("该医生在该时间段已经被排班了");
        }
        //看排班地址是否冲突
        Integer addressConflict = schedulingMapper.selectAddressConflict(scheduling);
        if (addressConflict >= 1){
            return Result.fail("该地址在该时间段已经被排班了");
        }
        //设置其它属性
        scheduling.setLeaveCount(scheduling.getCount());
        scheduling.setState(1);
        Integer isAlternate = schedulingMapper.selectIsAlternate(scheduling);
        scheduling.setIsAlternate(isAlternate);
        //插入
        int rows = schedulingMapper.insert(scheduling);
        Db.jedis.del(RedisConstant.SCHEDULING_STATE + scheduling.getCid() + "-" + DateUtil.getDate(new Date()));
        return rows == 1 ? Result.ok():Result.fail("失败");
    }

    @Override
    public Result update(Scheduling scheduling) {
        //看医生是否排班冲突
        Integer doctorConflict = schedulingMapper.selectDoctorConflict(scheduling);
        if (doctorConflict > 1){
            return Result.fail("该医生在该时间段已经被排班了");
        }
        //看排班地址是否冲突
        Integer addressConflict = schedulingMapper.selectAddressConflict(scheduling);
        if (addressConflict >= 1){
            return Result.fail("该地址在该时间段已经被排班了");
        }
        Scheduling oldScheduling = schedulingMapper.selectByPrimaryKey(scheduling.getId());
        if (oldScheduling == null){
            return Result.fail("该排班记录不存在");
        }
        //修改
        int rows = schedulingMapper.updateByPrimaryKey(scheduling);
        Db.jedis.del(RedisConstant.SCHEDULING_STATE + scheduling.getCid() + "-" + DateUtil.getDate(new Date()));
        return rows == 1 ? Result.ok():Result.fail("失败");
    }

    @Override
    public Result selByDoc(Integer did) {
        List<Scheduling> schedulings = schedulingMapper.selectByDid(did);
        return Result.ok(schedulings);
    }

    @Override
    public Result getNowScheduling(Integer did) {
        Scheduling scheduling = schedulingMapper.selectNowScheduling(did);
        return Result.ok(scheduling);
    }

}
